package com.wld.xm.framework.core.util;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSON;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.Response;
import com.wld.xm.framework.core.common.WebContent;
import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @date 2018/5/31 0031  10:00
 */
public class AsyncHttpKit {
    static final Logger log = LoggerFactory.getLogger(AsyncHttpKit.class);

    private AsyncHttpKit() {
    }

    ;

    private static final String DEFAULT_CHARSET = "UTF-8";
    private static final long DEFEAT_TIMEOUT = 10; // 默认10秒超时
    private static final TimeUnit DEFEAT_UNIT = TimeUnit.SECONDS; // 秒

    /**
     * 获取请求结果
     *
     * @param future 调用请求后，得到的Futrue对象，如果获取失败，将抛出4种结果异常
     * @return
     */
    public static String getResult(Future<Response> future) {
        String result = getResult(future, null, null);
        return result;
    }

    /**
     * @param future  调用请求后，得到的Futrue对象，如果获取失败，将抛出4种结果异常
     * @param timeOut 指定该次获取等待的结果
     * @param charset 指定用什么编码获取该结果
     * @return
     */
    public static String getResult(Future<Response> future, Long timeOut, String charset) {
        Response response;
        String result = null;

        Long s_timeOut = timeOut == null ? DEFEAT_TIMEOUT : timeOut;
        String s_chareset = charset == null ? DEFAULT_CHARSET : charset;
        try {
            response = future.get(s_timeOut, DEFEAT_UNIT);
            response = future.get();
            result = response.getResponseBody(s_chareset);
        } catch (Exception e) {
            throw new RuntimeException("获取结果出现错误：" + e.getMessage());
        }
        return result;
    }

    /**
     * Get请求
     *
     * @param http
     * @param url
     * @param params  参数，key - value ，其中key 和 value 都不能为null，否则出错
     * @param headers 请求头
     * @return
     */
    public static Future<Response> get(AsyncHttpClient http, String url, Map<String, String> params,
                                       Map<String, String> headers) {
        AsyncHttpClient.BoundRequestBuilder builder = http.prepareGet(url);
        if (params != null && !params.isEmpty()) {
            Set<String> keys = params.keySet();
            for (String key : keys) {
                builder.addQueryParam(key, params.get(key));
            }
        }

        if (headers != null && !headers.isEmpty()) {
            Set<String> keys = headers.keySet();
            for (String key : keys) {
                builder.addHeader(key, params.get(key));
            }
        }
        Future<Response> f = null;
        f = builder.execute();
        return f;
    }

    /**
     * Get请求
     *
     * @param http
     * @param url
     * @param params 参数key - value ，其中key 和 value 都不能为null，否则出错
     * @return
     */
    public static Future<Response> get(AsyncHttpClient http, String url, Map<String, String> params) {
        return get(http, url, params, null);
    }

    /**
     * Get请求
     *
     * @param http
     * @param url
     * @return
     */
    public static Future<Response> get(AsyncHttpClient http, String url) {
        return get(http, url, null);
    }

    /**
     * Post请求
     *
     * @param http
     * @param url
     * @param params 请求参数key - value ，其中key 和 value 都不能为null，否则出错
     * @return
     */
    public static Future<Response> post(AsyncHttpClient http, String url, Map<String, String> params) {
        AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
        log.info("请求参数:" + params.toString());
        log.info("请求地址:" + url);
        builder.setBodyEncoding(DEFAULT_CHARSET);
        if (params != null && !params.isEmpty()) {
            Set<String> keys = params.keySet();
            for (String key : keys) {
                builder.addQueryParam(key, params.get(key));  //1.9版本没有此api，是QueryParam，如果用次参数发送请求，会出现各种乱码
            }
        }
        builder.addHeader("Content-Type", "application/json");
        Future<Response> f = null;
        f = builder.execute();
        return f;
    }

    /**
     * PAY_POST请求
     *
     * @param http
     * @param url
     * @param obj
     * @return
     */
    public static Future<Response> post(AsyncHttpClient http, String url, Object obj) {
        AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
        builder.setBodyEncoding(DEFAULT_CHARSET);
        String body = JSON.toJSONString(obj);
        log.info("请求参数:" + body);
        log.info("请求地址:" + url);
        builder.setBody(body);
        byte[] buffer = body.getBytes();
        byte[] keyByte = WebContent.KEY_DATA.getBytes();
        byte[] tmpBuf = ArrayUtils.addAll(buffer, keyByte);
        String md5 = MD5Util.Encode16(tmpBuf);
        builder.addHeader("Content-Type", "application/json");
        builder.addHeader("md5", md5);
        Future<Response> f = null;
        f = builder.execute();
        return f;
    }
}
